package fr.cavalier.netcheck.dao;

import java.io.File;
import java.io.FileOutputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * <p>
 * Acces XML generique et gestion des exceptions
 * </p>
 * 
 * @author ccavalier
 * @date 26 janv. 2013 net-check fr.cavalier.netcheck.dao XmlParser.java
 */
public class XmlParser {
	private String xslSheet;

	public void setXslSheet(String s) {
		xslSheet = s;
	}

	public String getDtdFile() {
		return dtdFile;
	}

	public void setDtdFile(String dtdFile) {
		this.dtdFile = dtdFile;
	}

	protected Document doc;
	protected DefaultHandler gestionnaire;
	protected String dtdFile;

	/**
	 * <p>
	 * Methode en charge de l'ouverture et extraction du fichier xml
	 * </p>
	 */
	public void initializeDocumentFromFile(String fileName) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setValidating(true);
		factory.setNamespaceAware(true);
		factory.setAttribute(
				"http://java.sun.com/xml/jaxp/properties/schemaLanguage",
				"http://www.w3.org/2001/XMLSchema");
		Document document = null;
		try {
			File f = new File("src/main/resources/" + fileName + ".xml");
			DocumentBuilder builder = factory.newDocumentBuilder();
			if (!f.exists()) {
				document = builder.newDocument();
			} else {
				document = builder.parse(f);
			}
		} catch (SAXParseException spe) {
			// Error generated by the parser
			System.out.println("\n** Parsing error" + ", line "
					+ spe.getLineNumber() + ", uri " + spe.getSystemId());
			System.out.println("  " + spe.getMessage());
			Exception x = spe;
			if (spe.getException() != null)
				x = spe.getException();
			x.printStackTrace();
		} catch (Exception sxe) {
			sxe.printStackTrace();
		}
		doc = document;
	}

	/**
	 * <p>
	 * Methode en charge de l'ouverture et extraction du fichier xml
	 * </p>
	 * 
	 * @throws ParserConfigurationException
	 */
	public void initializeDocument() throws ParserConfigurationException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setValidating(true);
		factory.setNamespaceAware(true);
		factory.setAttribute(
				"http://java.sun.com/xml/jaxp/properties/schemaLanguage",
				"http://www.w3.org/2001/XMLSchema");
		doc = factory.newDocumentBuilder().newDocument();
	}

	/**
	 * <p>
	 * Enregistre les modifications de fichier xml
	 * </p>
	 */
	public void saveDocumentToFile(String output) {
		try {
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			if (dtdFile != null)
				transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
						dtdFile);

			FileOutputStream oFile = new FileOutputStream("src/main/resources/"
					+ output + ".xml");
			StreamResult result = new StreamResult(oFile);
			transformer.transform(source, result);
			
			// pour définir une feuille de style

			if (xslSheet != null && !xslSheet.equals("")) {
				TransformerFactory xsFactory = TransformerFactory.newInstance();
				Transformer xsTransformer = xsFactory
						.newTransformer(new StreamSource("src/main/resources/"+xslSheet + ".xsl"));

				xsTransformer.transform(new StreamSource("src/main/resources/"
						+ output + ".xml"),
						new StreamResult("src/main/resources/"
								+ output + ".html"));

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * <p>
	 * Initialise le parseur sax avec le gestionnaire adequat
	 * </p>
	 */
	public void parse(String input) {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser parseur = factory.newSAXParser();
			File fichier = new File("src/main/resources/" + input + ".xml");
			if (fichier.exists()) {
				parseur.parse(fichier, gestionnaire);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public DefaultHandler getGestionnaire() {
		return gestionnaire;
	}

	public void setGestionnaire(DefaultHandler gestionnaire) {
		this.gestionnaire = gestionnaire;
	}

	public void cleanDocument() throws ParserConfigurationException {
		if (this.doc == null) {
			initializeDocument();
		} else if (this.doc.getFirstChild() != null) {
			this.doc.removeChild(this.doc.getFirstChild());
		}
	}

}
